home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / tcsh / dist / tc.os.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-21  |  25.7 KB  |  1,161 lines

  1. /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.01/RCS/tc.os.c,v 3.13 1991/12/19 22:34:14 christos Exp $ */
  2. /*
  3.  * tc.os.c: OS Dependent builtin functions
  4.  */
  5. /*-
  6.  * Copyright (c) 1980, 1991 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions
  11.  * are met:
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer.
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in the
  16.  *    documentation and/or other materials provided with the distribution.
  17.  * 3. All advertising materials mentioning features or use of this software
  18.  *    must display the following acknowledgement:
  19.  *    This product includes software developed by the University of
  20.  *    California, Berkeley and its contributors.
  21.  * 4. Neither the name of the University nor the names of its contributors
  22.  *    may be used to endorse or promote products derived from this software
  23.  *    without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  */
  37. #include "sh.h"
  38.  
  39. RCSID("$Id: tc.os.c,v 3.13 1991/12/19 22:34:14 christos Exp $")
  40.  
  41. #include "tw.h"
  42. #include "ed.h"
  43. #include "ed.defns.h"        /* for the function names */
  44.  
  45. #ifdef titan
  46. int     end;
  47. #endif                /* titan */
  48.  
  49. /***
  50.  *** MACH
  51.  ***/
  52.  
  53. #ifdef MACH
  54. /* dosetpath -- setpath built-in command
  55.  *
  56.  **********************************************************************
  57.  * HISTORY
  58.  * 08-May-88  Richard Draves (rpd) at Carnegie-Mellon University
  59.  *    Major changes to remove artificial limits on sizes and numbers
  60.  *    of paths.
  61.  *
  62.  **********************************************************************
  63.  */
  64.  
  65. #ifdef MACH
  66. static Char STRCPATH[] = {'C', 'P', 'A', 'T', 'H', '\0'};
  67. static Char STRLPATH[] = {'L', 'P', 'A', 'T', 'H', '\0'};
  68. static Char STRMPATH[] = {'M', 'P', 'A', 'T', 'H', '\0'};
  69. static Char STREPATH[] = {'E', 'P', 'A', 'T', 'H', '\0'};
  70. #endif                /* MACH */
  71.  
  72. static Char *syspaths[] = {STRPATH, STRCPATH, STRLPATH, STRMPATH, STREPATH, 0};
  73. #define LOCALSYSPATH    "/usr/cs"
  74.  
  75. /*ARGSUSED*/
  76. void
  77. dosetpath(arglist, c)
  78.     Char  **arglist;
  79.     struct command *c;
  80. {
  81.     extern char *getenv();
  82.     sigmask_t omask;
  83.     Char  **pathvars, **cmdargs;
  84.     Char  **paths;
  85.     char  **spaths, **cpaths, **cmds;
  86.     char   *tcp;
  87.     unsigned int npaths, ncmds;
  88.     int     i, sysflag;
  89.  
  90.     omask = sigsetmask(sigmask(SIGINT));
  91.  
  92.     /*
  93.      * setpath(3) uses stdio and we want 0, 1, 2 to work...
  94.      */
  95.     if (!didfds) {
  96.     (void) dcopy(SHIN, 0);
  97.     (void) dcopy(SHOUT, 1);
  98.     (void) dcopy(SHDIAG, 2);
  99.     didfds = 1;
  100.     }
  101.  
  102.     for (i = 1; arglist[i] && (arglist[i][0] != '-'); i++);
  103.     npaths = i - 1;
  104.  
  105.     cmdargs = &arglist[i];
  106.     for (; arglist[i]; i++);
  107.     ncmds = i - npaths - 1;
  108.  
  109.     if (npaths) {
  110.     sysflag = 0;
  111.     pathvars = &arglist[1];
  112.     }
  113.     else {
  114.     sysflag = 1;
  115.     npaths = (sizeof syspaths / sizeof *syspaths) - 1;
  116.     pathvars = syspaths;
  117.     }
  118.  
  119.     /* note that npaths != 0 */
  120.  
  121.     spaths = (char **) xmalloc(npaths * sizeof *spaths);
  122.     setzero((char *) spaths, npaths * sizeof *spaths);
  123.     paths = (Char **) xmalloc((npaths + 1) * sizeof *paths);
  124.     setzero((char *) paths, (npaths + 1) * sizeof *paths);
  125.     cpaths = (char **) xmalloc((npaths + 1) * sizeof *cpaths);
  126.     setzero((char *) cpaths, (npaths + 1) * sizeof *cpaths);
  127.     cmds = (char **) xmalloc((ncmds + 1) * sizeof *cmds);
  128.     setzero((char *) cmds, (ncmds + 1) * sizeof *cmds);
  129.     for (i = 0; i < npaths; i++) {
  130.     char   *val = getenv(short2str(pathvars[i]));
  131.  
  132.     if (val == NULL)
  133.         val = "";
  134.  
  135.     spaths[i] = xmalloc((Strlen(pathvars[i]) + strlen(val)
  136.                  + 2) * sizeof **spaths);
  137.     (void) strcpy(spaths[i], short2str(pathvars[i]));
  138.     (void) strcat(spaths[i], "=");
  139.     (void) strcat(spaths[i], val);
  140.     cpaths[i] = spaths[i];
  141.     }
  142.  
  143.     for (i = 0; i < ncmds; i++) {
  144.     Char   *val = globone(cmdargs[i], G_ERROR);
  145.  
  146.     if (val == NULL)
  147.         goto abortpath;
  148.     cmds[i] = xmalloc(Strlen(val) + 1);
  149.     (void) strcpy(cmds[i], short2str(val));
  150.     }
  151.  
  152.  
  153.     if (setpath(cpaths, cmds, LOCALSYSPATH, sysflag, 1) < 0) {
  154. abortpath:
  155.     if (spaths) {
  156.         for (i = 0; i < npaths; i++)
  157.         if (spaths[i])
  158.             xfree((ptr_t) spaths[i]);
  159.         xfree((ptr_t) spaths);
  160.     }
  161.     if (paths) {
  162.         for (i = 0; i < npaths; i++)
  163.         if (paths[i])
  164.             xfree((ptr_t) paths[i]);
  165.         xfree((ptr_t) paths);
  166.     }
  167.     if (cpaths)
  168.         xfree((ptr_t) cpaths);
  169.     if (cmds) {
  170.         for (i = 0; i < ncmds; i++)
  171.         if (cmds[i])
  172.             xfree((ptr_t) cmds[i]);
  173.         xfree((ptr_t) cmds);
  174.     }
  175.  
  176.     for (i = 0; i < npaths; i++) {
  177.         paths[i] = SAVE(cpaths[i]);
  178.         xfree((ptr_t) cpaths[i]);
  179.     }
  180.     (void) sigsetmask(omask);
  181.     donefds();
  182.     return;
  183.     }
  184.  
  185.     for (i = 0; i < npaths; i++) {
  186.     Char   *val;
  187.  
  188.     for (val = paths[i]; val && *val && *val != '='; val++);
  189.     if (val && *val == '=') {
  190.         *val++ = '\0';
  191.         setenv(paths[i], val);
  192.         if (Strcmp(paths[i], STRPATH) == 0) {
  193.         importpath(val);
  194.         if (havhash)
  195.             dohash(NULL, NULL);
  196.         }
  197.         *--val = '=';
  198.     }
  199.     }
  200.     (void) sigsetmask(omask);
  201.     donefds();
  202. }
  203. #endif /* MACH */
  204.  
  205. /***
  206.  *** AIX
  207.  ***/
  208. #ifdef TCF
  209. /* ARGSUSED */
  210. void
  211. dogetxvers(v, c)
  212.     Char  **v;
  213.     struct command *c;
  214. {
  215.     char    xvers[MAXPATHLEN];
  216.  
  217.     if (getxvers(xvers, MAXPATHLEN) == -1)
  218.     stderror(ERR_SYSTEM, "getxvers", strerror(errno));
  219.     xprintf("%s\n", xvers);
  220.     flush();
  221. }
  222.  
  223. /*ARGSUSED*/
  224. void
  225. dosetxvers(v, c)
  226.     Char  **v;
  227.     struct command *c;
  228. {
  229.     char   *xvers;
  230.  
  231.     ++v;
  232.     if (!*v || *v[0] == '\0')
  233.     xvers = "";
  234.     else
  235.     xvers = short2str(*v);
  236.     if (setxvers(xvers) == -1)
  237.     stderror(ERR_SYSTEM, "setxvers", strerror(errno));
  238. }
  239.  
  240. #include <sf.h>
  241. #ifdef _AIXPS2
  242. # define XC_PDP11    0x01
  243. # define XC_23        0x02
  244. # define XC_Z8K        0x03
  245. # define XC_8086    0x04
  246. # define XC_68K        0x05
  247. # define XC_Z80        0x06
  248. # define XC_VAX        0x07
  249. # define XC_16032    0x08
  250. # define XC_286        0x09
  251. # define XC_386        0x0a
  252. # define XC_S370    0x0b
  253. #else
  254. # include <sys/x.out.h>
  255. #endif /* _AIXPS2 */
  256.  
  257. static struct xc_cpu_t {
  258.     short   xc_id;
  259.     char   *xc_name;
  260. }       xcpu[] =
  261. {
  262.     { XC_PDP11,    "pdp11"   },
  263.     { XC_23,    "i370"    },
  264.     { XC_Z8K,    "z8000"   },
  265.     { XC_8086,    "i86"      },
  266.     { XC_68K,    "mc68000" },
  267.     { XC_Z80,    "x80"      },
  268.     { XC_VAX,    "vax"      },
  269.     { XC_16032,    "ns16032" },
  270.     { XC_286,    "i286"      },
  271.     { XC_386,    "i386"      },
  272.     { XC_S370,    "xa370"      },
  273.     { 0,    NULL      }
  274. };
  275.  
  276. /*
  277.  * our local hack table, stolen from x.out.h
  278.  */
  279. static char *
  280. getxcode(xcid)
  281.     short   xcid;
  282. {
  283.     int     i;
  284.  
  285.     for (i = 0; xcpu[i].xc_name != NULL; i++)
  286.     if (xcpu[i].xc_id == xcid)
  287.         return (xcpu[i].xc_name);
  288.     return (NULL);
  289. }
  290.  
  291. static short
  292. getxid(xcname)
  293.     char   *xcname;
  294. {
  295.     int     i;
  296.  
  297.     for (i = 0; xcpu[i].xc_name != NULL; i++)
  298.     if (strcmp(xcpu[i].xc_name, xcname) == 0)
  299.         return (xcpu[i].xc_id);
  300.     return ((short) -1);
  301. }
  302.  
  303.  
  304. /*ARGSUSED*/
  305. void
  306. dogetspath(v, c)
  307.     Char  **v;
  308.     struct command *c;
  309. {
  310.     int     i, j;
  311.     sitepath_t p[MAXSITE];
  312.     struct sf *st;
  313.     static char *local = "LOCAL ";
  314.  
  315.     if ((j = getspath(p, MAXSITE)) == -1)
  316.     stderror(ERR_SYSTEM, "getspath", strerror(errno));
  317.     for (i = 0; i < j && (p[i] & SPATH_CPU) != NOSITE; i++) {
  318.     if (p[i] & SPATH_CPU) {
  319.         if ((p[i] & SPATH_MASK) == NULLSITE)
  320.         xprintf(local);
  321.         else if ((st = sfxcode((short) (p[i] & SPATH_MASK))) != NULL)
  322.         xprintf("%s ", st->sf_ctype);
  323.         else {
  324.         char   *xc = getxcode(p[i] & SPATH_MASK);
  325.  
  326.         if (xc != NULL)
  327.             xprintf("%s ", xc);
  328.         else
  329.             xprintf("*cpu %d* ", (int) (p[i] & SPATH_MASK));
  330.         /* 
  331.          * BUG in the aix code... needs that cause if
  332.          * sfxcode fails once it fails for ever 
  333.          */
  334.         endsf();    
  335.         }
  336.     }
  337.     else {
  338.         if (p[i] == NULLSITE)
  339.         xprintf(local);
  340.         else if ((st = sfnum(p[i])) != NULL)
  341.         xprintf("%s ", st->sf_sname);
  342.         else
  343.         xprintf("*site %d* ", (int) (p[i] & SPATH_MASK));
  344.     }
  345.     }
  346.     xprintf("\n");
  347.     flush();
  348. }
  349.  
  350. /*ARGSUSED*/
  351. void
  352. dosetspath(v, c)
  353.     Char  **v;
  354.     struct command *c;
  355. {
  356.     int     i;
  357.     short   j;
  358.     char   *s;
  359.     sitepath_t p[MAXSITE];
  360.     struct sf *st;
  361.  
  362.     for (i = 0, v++; *v && *v[0] != '\0'; v++, i++) {
  363.     s = short2str(*v);
  364.     if (Isdigit(*s))
  365.         p[i] = atoi(s);
  366.     else if (strcmp(s, "LOCAL") == 0)
  367.         p[i] = NULLSITE;
  368.     else if ((st = sfctype(s)) != NULL)
  369.         p[i] = SPATH_CPU | st->sf_ccode;
  370.     else if ((j = getxid(s)) != -1)
  371.         p[i] = SPATH_CPU | j;
  372.     else if ((st = sfname(s)) != NULL)
  373.         p[i] = st->sf_id;
  374.     else {
  375.         setname(s);
  376.         stderror(ERR_NAME | ERR_STRING, "Bad cpu/site name");
  377.     }
  378.     if (i == MAXSITE - 1)
  379.         stderror(ERR_NAME | ERR_STRING, "Site path too long");
  380.     }
  381.     if (setspath(p, i) == -1)
  382.     stderror(ERR_SYSTEM, "setspath", strerror(errno));
  383. }
  384.  
  385. /* sitename():
  386.  *    Return the site name where the process is running
  387.  */
  388. char   *
  389. sitename(pid)
  390.     pid_t   pid;
  391. {
  392.     siteno_t ss;
  393.     struct sf *st;
  394.  
  395.     if ((ss = site(pid)) == -1 || (st = sfnum(ss)) == NULL)
  396.     return ("unknown");
  397.     else
  398.     return (st->sf_sname);
  399. }
  400.  
  401. static int
  402. migratepid(pid, new_site)
  403.     pid_t   pid;
  404.     siteno_t new_site;
  405. {
  406.     struct sf *st;
  407.     int     need_local;
  408.  
  409.     need_local = (pid == 0) || (pid == getpid());
  410.  
  411.     if (kill3((pid_t) pid, SIGMIGRATE, new_site) < 0) {
  412.     xprintf("%d: %s\n", pid, strerror(errno));
  413.     return (-1);
  414.     }
  415.  
  416.     if (need_local) {
  417.     if ((new_site = site(0)) == -1) {
  418.         xprintf("site: %s\n", strerror(errno));
  419.         return (-1);
  420.     }
  421.     if ((st = sfnum(new_site)) == NULL) {
  422.         xprintf("%d: Site not found\n", new_site);
  423.         return (-1);
  424.     }
  425.     if (setlocal(st->sf_local, strlen(st->sf_local)) == -1) {
  426.         xprintf("setlocal: %s: %s\n", st->sf_local, strerror(errno));
  427.         return (-1);
  428.     }
  429.     }
  430.     return (0);
  431. }
  432.  
  433. /*ARGSUSED*/
  434. void
  435. domigrate(v, c)
  436.     Char  **v;
  437.     struct command *c;
  438. {
  439.     struct sf *st;
  440.     char   *s;
  441.     Char   *cp;
  442.     struct process *pp;
  443.     int     pid, err1 = 0;
  444.     siteno_t new_site = 0;
  445.     sigmask_t omask;
  446.  
  447. #ifdef BSDSIGS
  448.     omask = sigmask(SIGCHLD);
  449.     if (setintr)
  450.     omask |= sigmask(SIGINT);
  451.     omask = sigblock(omask) & ~omask;
  452. #else
  453.     if (setintr)
  454.     (void) sighold(SIGINT);
  455.     (void) sighold(SIGCHLD);
  456. #endif /* BSDSIGS */
  457.  
  458.     ++v;
  459.     if (*v[0] == '-') {
  460.     /*
  461.      * Do the -site.
  462.      */
  463.     s = short2str(&v[0][1]);
  464.     if ((st = sfname(s)) == NULL) {
  465.         setname(s);
  466.         stderror(ERR_NAME | ERR_STRING, "Site not found");
  467.     }
  468.     new_site = st->sf_id;
  469.     ++v;
  470.     }
  471.  
  472.     if (!*v || *v[0] == '\0') {
  473.     if (migratepid(0, new_site) == -1)
  474.         err1++;
  475.     }
  476.     else {
  477.     gflag = 0, tglob(v);
  478.     if (gflag) {
  479.         v = globall(v);
  480.         if (v == 0)
  481.         stderror(ERR_NAME | ERR_NOMATCH);
  482.     }
  483.     else {
  484.         v = gargv = saveblk(v);
  485.         trim(v);
  486.     }
  487.  
  488.     while (v && (cp = *v)) {
  489.         if (*cp == '%') {
  490.         pp = pfind(cp);
  491.         if (kill3((pid_t) - pp->p_jobid, SIGMIGRATE, new_site) < 0) {
  492.             xprintf("%s: %s\n", short2str(cp), strerror(errno));
  493.             err1++;
  494.         }
  495.         }
  496.         else if (!(Isdigit(*cp) || *cp == '-'))
  497.         stderror(ERR_NAME | ERR_JOBARGS);
  498.         else {
  499.         pid = atoi(short2str(cp));
  500.         if (migratepid(pid, new_site) == -1)
  501.             err1++;
  502.         }
  503.         v++;
  504.     }
  505.     if (gargv)
  506.         blkfree(gargv), gargv = 0;
  507.     }
  508.  
  509. done:
  510. #ifdef BSDSIGS
  511.     (void) sigsetmask(omask);
  512. #else
  513.     (void) sigrelse(SIGCHLD);
  514.     if (setintr)
  515.     (void) sigrelse(SIGINT);
  516. #endif /* BSDSIGS */
  517.     if (err1)
  518.     stderror(ERR_SILENT);
  519. }
  520.  
  521. #endif /* TCF */
  522.  
  523. /***
  524.  *** CONVEX Warps.
  525.  ***/
  526.  
  527. #ifdef WARP
  528. /*
  529.  * handle the funky warping of symlinks
  530.  */
  531. #include <warpdb.h>
  532. #include <sys/warp.h>
  533.  
  534. static jmp_buf sigsys_buf;
  535.  
  536. static  sigret_t
  537. catch_sigsys()
  538. {
  539.     longjmp(sigsys_buf, 1);
  540. }
  541.  
  542.  
  543. /*ARGSUSED*/
  544. void
  545. dowarp(v, c)
  546.     Char  **v;
  547.     struct command *c;
  548. {
  549.     int     warp, oldwarp;
  550.     struct warpent *we;
  551.     void    (*old_sigsys_handler) () = 0;
  552.     char   *newwarp;
  553.  
  554.     if (setjmp(sigsys_buf)) {
  555.     signal(SIGSYS, old_sigsys_handler);
  556.     stderror(ERR_NAME | ERR_STRING, 
  557.          "You're trapped in a universe you never made");
  558.     return;
  559.     }
  560.     old_sigsys_handler = signal(SIGSYS, catch_sigsys);
  561.  
  562.     warp = getwarp();
  563.  
  564.     v++;
  565.     if (*v == 0) {        /* display warp value */
  566.     if (warp < 0)
  567.         stderror(ERR_NAME | ERR_STRING, "Getwarp failed");
  568.     we = getwarpbyvalue(warp);
  569.     if (we)
  570.         printf("%s\n", we->w_name);
  571.     else
  572.         printf("%d\n", warp);
  573.     }
  574.     else {            /* set warp value */
  575.     oldwarp = warp;
  576.     newwarp = short2str(*v);
  577.     if (Isdigit(*v[0]))
  578.         warp = atoi(newwarp);
  579.     else {
  580.         we = getwarpbyname(newwarp);
  581.         if (we)
  582.         warp = we->w_value;
  583.         else
  584.         warp = -1;
  585.     }
  586.     if ((warp < 0) || (warp >= WARP_MAXLINK))
  587.         stderror(ERR_NAME | ERR_STRING, "Invalid warp");
  588.     if ((setwarp(warp) < 0) || (getwarp() != warp)) {
  589.         (void) setwarp(oldwarp);
  590.         stderror(ERR_NAME | ERR_STRING, "Setwarp failed");
  591.     }
  592.     }
  593.     signal(SIGSYS, old_sigsys_handler);
  594.     return;
  595. }
  596. #endif /* WARP */
  597.  
  598. /***
  599.  *** Masscomp
  600.  ***/
  601. /* Added, DAS DEC-90. */
  602. #ifdef masscomp
  603. /*ARGSUSED*/
  604. void
  605. douniverse(v, c)
  606.     register Char **v;
  607.     struct command *c;
  608. {
  609.     register Char *cp = v[1];
  610.     char    ubuf[100];
  611.  
  612.     if (cp == 0) {
  613.     (void) getuniverse(ubuf);
  614.     xprintf("%s\n", ubuf);
  615.     }
  616.     else if (*cp == '\0' || setuniverse(short2str(cp)) != 0)
  617.     stderror(ERR_NAME | ERR_STRING, "Illegal universe");
  618. }
  619. #endif /* masscomp */
  620.  
  621.  
  622. #ifdef _SEQUENT_
  623. /*
  624.  * Compute the difference in process stats.
  625.  */
  626. void
  627. pr_stat_sub(p2, p1, pr)
  628.     struct process_stats *p2, *p1, *pr;
  629. {
  630.     pr->ps_utime.tv_sec = p2->ps_utime.tv_sec - p1->ps_utime.tv_sec;
  631.     pr->ps_utime.tv_usec = p2->ps_utime.tv_usec - p1->ps_utime.tv_usec;
  632.     if (pr->ps_utime.tv_usec < 0) {
  633.     pr->ps_utime.tv_sec -= 1;
  634.     pr->ps_utime.tv_usec += 1000000;
  635.     }
  636.     pr->ps_stime.tv_sec = p2->ps_stime.tv_sec - p1->ps_stime.tv_sec;
  637.     pr->ps_stime.tv_usec = p2->ps_stime.tv_usec - p1->ps_stime.tv_usec;
  638.     if (pr->ps_stime.tv_usec < 0) {
  639.     pr->ps_stime.tv_sec -= 1;
  640.     pr->ps_stime.tv_usec += 1000000;
  641.     }
  642.  
  643.     pr->ps_maxrss = p2->ps_maxrss - p1->ps_maxrss;
  644.     pr->ps_pagein = p2->ps_pagein - p1->ps_pagein;
  645.     pr->ps_reclaim = p2->ps_reclaim - p1->ps_reclaim;
  646.     pr->ps_zerofill = p2->ps_zerofill - p1->ps_zerofill;
  647.     pr->ps_pffincr = p2->ps_pffincr - p1->ps_pffincr;
  648.     pr->ps_pffdecr = p2->ps_pffdecr - p1->ps_pffdecr;
  649.     pr->ps_swap = p2->ps_swap - p1->ps_swap;
  650.     pr->ps_syscall = p2->ps_syscall - p1->ps_syscall;
  651.     pr->ps_volcsw = p2->ps_volcsw - p1->ps_volcsw;
  652.     pr->ps_involcsw = p2->ps_involcsw - p1->ps_involcsw;
  653.     pr->ps_signal = p2->ps_signal - p1->ps_signal;
  654.     pr->ps_lread = p2->ps_lread - p1->ps_lread;
  655.     pr->ps_lwrite = p2->ps_lwrite - p1->ps_lwrite;
  656.     pr->ps_bread = p2->ps_bread - p1->ps_bread;
  657.     pr->ps_bwrite = p2->ps_bwrite - p1->ps_bwrite;
  658.     pr->ps_phread = p2->ps_phread - p1->ps_phread;
  659.     pr->ps_phwrite = p2->ps_phwrite - p1->ps_phwrite;
  660. }
  661.  
  662. #endif /* _SEQUENT_ */
  663.  
  664.  
  665. #ifdef tcgetpgrp
  666. int
  667. xtcgetpgrp(fd)
  668.     int     fd;
  669. {
  670.     int     pgrp;
  671.  
  672.     /* ioctl will handle setting errno correctly. */
  673.     if (ioctl(fd, TIOCGPGRP, (ioctl_t) & pgrp) < 0)
  674.     return (-1);
  675.     return (pgrp);
  676. }
  677.  
  678. /*
  679.  * XXX: tcsetpgrp is not a macro any more cause on some systems,
  680.  * pid_t is a short, but the ioctl() takes a pointer to int (pyr)
  681.  * Thanks to Simon Day (simon@pharaoh.cyborg.bt.co.uk) for pointing
  682.  * this out.
  683.  */
  684. int
  685. xtcsetpgrp(fd, pgrp)
  686.     int fd, pgrp;
  687. {
  688.     return ioctl(fd, TIOCSPGRP, (ioctl_t) &pgrp);
  689. }
  690.  
  691. #endif    /* tcgetpgrp */
  692.  
  693.  
  694. #ifdef YPBUGS
  695. void
  696. fix_yp_bugs()
  697. {
  698.     char   *mydomain;
  699.  
  700.     /*
  701.      * PWP: The previous version assumed that yp domain was the same as the
  702.      * internet name domain.  This isn't allways true. (Thanks to Mat Landau
  703.      * <mlandau@bbn.com> for the original version of this.)
  704.      */
  705.     if (yp_get_default_domain(&mydomain) == 0) {    /* if we got a name */
  706.     extern void yp_unbind();
  707.  
  708.     yp_unbind(mydomain);
  709.     }
  710. }
  711.  
  712. #endif /* YPBUGS */
  713.  
  714.  
  715. void
  716. osinit()
  717. {
  718.     extern ptr_t membot;
  719.  
  720.     membot = (ptr_t) sbrk(0);
  721.  
  722. #ifdef OREO
  723.     set42sig();
  724.     sigignore(SIGIO);        /* ignore SIGIO */
  725. #endif /* OREO */
  726.  
  727. #ifdef aiws
  728.     {
  729.     struct sigstack inst;
  730.     inst.ss_sp = xmalloc(4192) + 4192;
  731.     inst.ss_onstack = 0;
  732.     sigstack(&inst, NULL);
  733.     }
  734. #endif /* aiws */
  735.  
  736. #ifdef titan
  737.     end = sbrk(0);
  738. #endif    /* titan */
  739.  
  740. #ifdef apollo
  741.     (void) isapad();
  742. #endif
  743. }
  744.  
  745. #ifdef strerror
  746. char *
  747. xstrerror(i)
  748.     int i;
  749. {
  750.     static char errbuf[40]; /* 64 bit num */
  751.  
  752.     if (i >= 0 && i < sys_nerr) 
  753.     return sys_errlist[i];
  754.     else {
  755.     xsprintf(errbuf, "Unknown Error: %d", i);
  756.     return errbuf;
  757.     }
  758. }
  759. #endif /* strerror */
  760.     
  761. #ifdef gethostname
  762. #include <sys/utsname.h>
  763.  
  764. int
  765. xgethostname(name, namlen)
  766.     char   *name;
  767.     int     namlen;
  768. {
  769.     int     i, retval;
  770.     struct utsname uts;
  771.  
  772.     retval = uname(&uts);
  773.  
  774. #ifdef DEBUG
  775.     xprintf("sysname:  %s\n", uts.sysname);
  776.     xprintf("nodename: %s\n", uts.nodename);
  777.     xprintf("release:  %s\n", uts.release);
  778.     xprintf("version:  %s\n", uts.version);
  779.     xprintf("machine:  %s\n", uts.machine);
  780. #endif                /* DEBUG */
  781.     i = strlen(uts.nodename) + 1;
  782.     (void) strncpy(name, uts.nodename, i < namlen ? i : namlen);
  783.  
  784.     return retval;
  785. }                /* end gethostname */
  786.  
  787. #endif                /* gethostname */
  788.  
  789.  
  790. #ifdef getwd
  791. static char *strrcpy __P((char *, char *));
  792.  
  793. /* xgetwd():
  794.  *    Return the pathname of the current directory, or return
  795.  *    an error message in pathname.
  796.  */
  797.  
  798. # ifdef hp9000s500
  799. /*
  800.  *  From: Bernd Mohr <mohr@faui77.informatik.uni-erlangen.de>
  801.  *  I also ported the tcsh to the HP9000 Series 500. This computer
  802.  *  is a little bit different than the other HP 9000 computer. It has
  803.  *  a HP Chip instead of a Motorola CPU and it is no "real" UNIX. It runs
  804.  *  HP-UX which is emulated in top of a HP operating system. So, the last
  805.  *  supported version of HP-UX is 5.2 on the HP9000s500. This has two
  806.  *  consequences: it supports no job control and it has a filesystem
  807.  *  without "." and ".." !!!
  808.  */
  809. static int pathsize;            /* pathname length */
  810.  
  811. char *
  812. xgetwd(pathname)
  813.     char *pathname;
  814. {
  815.     char pathbuf[MAXNAMLEN];    /* temporary pathname buffer */
  816.     char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */
  817.     char *prepend();        /* prepend dirname to pathname */
  818.     dev_t rdev;            /* root device number */
  819.     DIR *dirp;            /* directory stream */
  820.     ino_t rino;            /* root inode number */
  821.     off_t rsize;            /* root size */
  822.     struct direct *dir;        /* directory entry struct */
  823.     struct stat d ,dd;        /* file status struct */
  824.  
  825.     pathsize = 0;
  826.     *pnptr = '\0';
  827.     stat("/.", &d);
  828.     rdev = d.st_dev;
  829.     rino = d.st_ino;
  830.     rsize = d.st_size;
  831.     for (;;) {
  832.         stat(".", &d);
  833.         if (d.st_ino == rino && d.st_dev == rdev && d.st_size == rsize)
  834.             break;        /* reached root directory */
  835.         if ((dirp = opendir("..")) == NULL) {
  836.                 (void) xsprintf(pathname,
  837.                         "getwd: Cannot open \"..\" (%s)", strerror(errno));
  838.             goto fail;
  839.         }
  840.         if (chdir("..") < 0) {
  841.                 (void) xsprintf(pathname,
  842.                         "getwd: Cannot chdir to \"..\" (%s)", strerror(errno));
  843.             goto fail;
  844.         }
  845.         do {
  846.             if((dir = readdir(dirp)) == NULL) {
  847.                 closedir(dirp);
  848.                     (void) xsprintf(pathname,
  849.                             "getwd: Read error in \"..\" (%s)",
  850.                 strerror(errno));
  851.                 goto fail;
  852.             }
  853.             stat(dir->d_name, &dd);
  854.         } while (dd.st_ino  != d.st_ino  ||
  855.              dd.st_dev  != d.st_dev  ||
  856.              dd.st_size != d.st_size
  857.             );
  858.         closedir(dirp);
  859.         pnptr = prepend("/", prepend(dir->d_name, pnptr));
  860.     }
  861.  
  862.     if (*pnptr == '\0')        /* current dir == root dir */
  863.         strcpy(pathname, "/");
  864.     else {
  865.         strcpy(pathname, pnptr);
  866.         if (chdir(pnptr) < 0) {
  867.                 (void) xsprintf(pathname,
  868.                         "getwd: Cannot change back to \".\" (%s)",
  869.             strerror(errno));
  870.             return (NULL);
  871.         }
  872.     }
  873.     return (pathname);
  874.  
  875. fail:
  876.     chdir(prepend(".", pnptr));
  877.     return (NULL);
  878. }
  879.  
  880. /* prepend():
  881.  *     tacks a directory name onto the front of a pathname.
  882.  */
  883. static char *
  884. prepend(dirname, pathname)
  885.     register char *dirname;
  886.     register char *pathname;
  887. {
  888.     register int i;            /* directory name size counter */
  889.  
  890.     for (i = 0; *dirname != '\0'; i++, dirname++)
  891.         continue;
  892.     if ((pathsize += i) < MAXNAMLEN)
  893.         while (i-- > 0)
  894.             *--pathname = *--dirname;
  895.     return (pathname);
  896. }
  897.  
  898. # else /* ! hp9000s500 */
  899. char   *
  900. xgetwd(pathname)
  901.     char   *pathname;
  902. {
  903.     DIR    *dp;
  904.     struct dirent *d;
  905.  
  906.     struct stat st_root, st_cur, st_next, st_dot;
  907.     char    pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
  908.     char   *cur_name_add;
  909.     char   *pathptr, *nextpathptr;
  910.  
  911.     /* find the inode of root */
  912.     if (stat("/", &st_root) == -1) {
  913.     (void) xsprintf(pathname,
  914.             "getwd: Cannot stat \"/\" (%s)", strerror(errno));
  915.     return (NULL);
  916.     }
  917.     pathbuf[MAXPATHLEN - 1] = '\0';
  918.     pathptr = &pathbuf[MAXPATHLEN - 1];
  919.     nextpathbuf[MAXPATHLEN - 1] = '\0';
  920.     cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
  921.  
  922.     /* find the inode of the current directory */
  923.     if (lstat("./", &st_cur) == -1) {
  924.     (void) xsprintf(pathname,
  925.             "getwd: Cannot stat \".\" (%s)", strerror(errno));
  926.     return (NULL);
  927.     }
  928.     nextpathptr = strrcpy(nextpathptr, "../");
  929.  
  930.     /* Descend to root */
  931.     for (;;) {
  932.  
  933.     /* look if we found root yet */
  934.     if (st_cur.st_ino == st_root.st_ino &&
  935.         DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
  936.         (void) strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
  937.         return (pathname);
  938.     }
  939.  
  940.     /* open the parent directory */
  941.     if ((dp = opendir(nextpathptr)) == NULL) {
  942.         (void) xsprintf(pathname,
  943.                 "getwd: Cannot open directory \"%s\" (%s)",
  944.                 nextpathptr, strerror(errno));
  945.         return (NULL);
  946.     }
  947.  
  948.     /* look in the parent for the entry with the same inode */
  949.     for (d = readdir(dp); d != NULL; d = readdir(dp)) {
  950.         (void) strcpy(cur_name_add, d->d_name);
  951.         if (lstat(nextpathptr, &st_next) == -1) {
  952.         (void) xsprintf(pathname, "getwd: Cannot stat \"%s\" (%s)",
  953.                 d->d_name, strerror(errno));
  954.         return (NULL);
  955.         }
  956.         if (d->d_name[0] == '.' && d->d_name[1] == '\0')
  957.         st_dot = st_next;
  958.  
  959.         /* check if we found it yet */
  960.         if (st_next.st_ino == st_cur.st_ino &&
  961.         DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev)) {
  962.         st_cur = st_dot;
  963.         pathptr = strrcpy(pathptr, d->d_name);
  964.         pathptr = strrcpy(pathptr, "/");
  965.         nextpathptr = strrcpy(nextpathptr, "../");
  966.         *cur_name_add = '\0';
  967.         (void) closedir(dp);
  968.         break;
  969.         }
  970.     }
  971.     if (d == NULL) {
  972.         (void) xsprintf(pathname, "getwd: Cannot find \".\" in \"..\"");
  973.         return (NULL);
  974.     }
  975.     }
  976. } /* end getwd */
  977.  
  978. /* strrcpy():
  979.  *    Like strcpy, going backwards and returning the new pointer
  980.  */
  981. static char *
  982. strrcpy(ptr, str)
  983.     register char *ptr, *str;
  984. {
  985.     register int len = strlen(str);
  986.  
  987.     while (len)
  988.     *--ptr = str[--len];
  989.  
  990.     return (ptr);
  991. } /* end strrcpy */
  992. # endif /* hp9000s500 */
  993. #endif /* getwd */
  994.  
  995. #ifdef apollo
  996. /***
  997.  *** Domain/OS
  998.  ***/
  999. #undef value            /* XXX: Careful here */
  1000. #include <apollo/base.h>
  1001. #include <apollo/loader.h>
  1002. #include <apollo/error.h>
  1003.  
  1004.  
  1005. static char *
  1006. apperr(st)
  1007.     status_$t *st;
  1008. {
  1009.     static char buf[BUFSIZE];
  1010.     short e_subl, e_modl, e_codel;
  1011.     error_$string_t e_sub, e_mod, e_code;
  1012.  
  1013.     error_$get_text(*st, e_sub, &e_subl, e_mod, &e_modl, e_code, &e_codel);
  1014.     e_sub[e_subl] = '\0';
  1015.     e_code[e_codel] = '\0';
  1016.     e_mod[e_modl] = '\0';
  1017.     (void) xsprintf(buf, "%s (%s/%s)", e_code, e_sub, e_mod);
  1018.  
  1019.     return(buf);
  1020. }
  1021.  
  1022. static int
  1023. llib(s)
  1024.     Char *s;
  1025. {
  1026.     short len = Strlen(s);
  1027.     status_$t st;
  1028.     char *t;
  1029.  
  1030.     loader_$inlib(t = short2str(s), len, &st);
  1031.     if (st.all != status_$ok) 
  1032.     stderror(ERR_SYSTEM, t, apperr(&st));
  1033. }
  1034.  
  1035. /*ARGSUSED*/
  1036. void
  1037. doinlib(v, c)
  1038.     Char **v;
  1039.     struct command *c;
  1040. {
  1041.     setname(short2str(*v++));
  1042.     gflag = 0, tglob(v);
  1043.     if (gflag) {
  1044.     v = globall(v);
  1045.     if (v == 0)
  1046.         stderror(ERR_NAME | ERR_NOMATCH);
  1047.     }
  1048.     else {
  1049.     v = gargv = saveblk(v);
  1050.     trim(v);
  1051.     }
  1052.  
  1053.     while (v && *v) 
  1054.     llib(*v++);
  1055.     if (gargv)
  1056.     blkfree(gargv), gargv = 0;
  1057. }
  1058.  
  1059. int
  1060. getv(v)
  1061.     Char *v;
  1062. {
  1063.     if (eq(v, STRbsd43))
  1064.     return(1);
  1065.     else if (eq(v, STRsys53))
  1066.     return(0);
  1067.     else 
  1068.     stderror(ERR_NAME | ERR_SYSTEM, short2str(v), "Invalid system type");
  1069.     /*NOTREACHED*/
  1070.     return(0);
  1071. }
  1072.  
  1073. /*ARGSUSED*/
  1074. void
  1075. dover(v, c)
  1076.     Char **v;
  1077.     struct command *c;
  1078. {
  1079.     Char *p;
  1080.  
  1081.     setname(short2str(*v++));
  1082.     if (!*v) {
  1083.     if (!(p = Getenv(STRSYSTYPE)))
  1084.         stderror(ERR_NAME | ERR_STRING, "System type is not set");
  1085.     xprintf("%s\n", short2str(p));
  1086.     }
  1087.     else {
  1088.     Setenv(STRSYSTYPE, getv(*v) ? STRbsd43 : STRsys53);
  1089.     dohash(NULL, NULL);
  1090.     }
  1091. }
  1092.  
  1093. /*
  1094.  * Many thanks to rees@citi.umich.edu (Jim Rees) and
  1095.  *                mathys@ssdt-tempe.sps.mot.com (Yves Mathys)
  1096.  * For figuring out how to do this... I could have never done
  1097.  * it without their help.
  1098.  */
  1099. typedef short enum {
  1100.     name_$wdir_type,
  1101.     name_$ndir_type,
  1102.     name_$node_dir_type,
  1103. } name_$dir_type_t;
  1104.  
  1105. /*ARGSUSED*/
  1106. void
  1107. dorootnode(v, c)
  1108.     Char **v;
  1109.     struct command *c;
  1110. {
  1111.     name_$dir_type_t dirtype = name_$node_dir_type;
  1112.     uid_$t uid;
  1113.     status_$t st;
  1114.     char *name;
  1115.     short namelen;
  1116.  
  1117.     setname(short2str(*v++));
  1118.  
  1119.     name = short2str(*v);
  1120.     namelen = strlen(name);
  1121.  
  1122.     name_$resolve(name, &namelen, &uid, &st);
  1123.     if (st.all != status_$ok) 
  1124.     stderror(ERR_SYSTEM, name, apperr(&st));
  1125.     namelen = 0;
  1126.     name_$set_diru(&uid, "", &namelen, &dirtype, &st);
  1127.     if (st.all != status_$ok) 
  1128.     stderror(ERR_SYSTEM, name, apperr(&st));
  1129.     dohash(NULL, NULL);
  1130. }
  1131.  
  1132. int
  1133. isapad()
  1134. {
  1135.     static int res = -1;
  1136.     static status_$t st;
  1137.  
  1138.     if (res == -1) {
  1139.     int strm;
  1140.     if (isatty(0))
  1141.         strm = 0;
  1142.     if (isatty(1))
  1143.         strm = 1;
  1144.     if (isatty(2))
  1145.         strm = 2;
  1146.     else {
  1147.         res = 0;
  1148.         st.all = status_$ok;
  1149.         return(res);
  1150.     }
  1151.     res = stream_$isavt(&strm, &st);
  1152.     res = res ? 1 : 0;
  1153.     }
  1154.     else {
  1155.     if (st.all != status_$ok) 
  1156.         stderror(ERR_SYSTEM, "stream_$isavt", apperr(&st));
  1157.     }
  1158.     return(res);
  1159. }
  1160. #endif
  1161.